package com.service.wxconfig.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bean.*;
import com.bean.wx.Article;
import com.bean.wx.TextMessage;
import com.dao.*;
import com.service.core.AbstractService;
import com.service.wxconfig.WxConfigService;
import com.util.Config;
import com.util.EmojiFilter;
import com.util.HttpClient;
import com.bean.wx.NewsMessage;
import com.util.ImgUtil;
import com.util.wx.Image;
import com.util.wx.ImgMessage;
import com.util.wx.MessageUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2017/9/10.
 */
@Service
public class WxConfigServiceImpl extends AbstractService<Wx_config, Integer> implements WxConfigService {
    Logger logger = Logger.getLogger(WxConfigServiceImpl.class);

    @Autowired
    private Wx_userMapper wx_userMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private Mb_accountMapper mb_accountMapper;

    @Autowired
    private Wx_menuMapper wx_menuMapper;

    @Autowired
    private Wx_configMapper wx_configMapper;

    @Autowired
    private Wx_pic_replyMapper wx_pic_replyMapper;

    @Autowired
    private Wx_reply_keywordMapper wx_reply_keywordMapper;

    @Autowired
    private Wx_replyMapper wx_replyMapper;

    public String processRequest(HttpServletRequest request){
        String respMessage = "";
        try {
            // xml请求解析
            Map<String, String> requestMap = MessageUtil.parseXml(request);

            // 发送方帐号（open_id）
            String fromUserName = requestMap.get("FromUserName");
            // 公众帐号
            String toUserName = requestMap.get("ToUserName");
            // 消息类型

            String msgType = requestMap.get("MsgType");
            System.out.println("msgType:"+msgType);
            System.out.println("fromUserName:"+fromUserName);
            System.out.println("toUserName:"+toUserName);

            // 文本消息
            if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
                // 接收用户发送的文本消息内容
                String keyword = requestMap.get("Content");
                Wx_reply_keyword replyKeyWord = wx_reply_keywordMapper.selectByKeyword(keyword);
				/*存在关键字自动回复内容*/
                if(replyKeyWord!=null){
                    Integer replyId = replyKeyWord.getReplyid();
                    Wx_reply reply = wx_replyMapper.selectByPrimaryKey(replyId);
                    if(reply!=null){
                        if(reply.getMsgtype()==1){//回复文本消息
                            String replyStr = reply.getContent();
                            respMessage=this.createTextMessage(replyStr, fromUserName, toUserName);
                        }
                        else if(reply.getMsgtype()==2){//回复图文消息
                            Integer picId = reply.getReplypicid();
                        }
                    }
                }else{
                    if("创建菜单".equals(keyword)){
                        logger.info("创建菜单开始");
                        this.createMenu();
                        logger.info("创建菜单结束");
                    }else{
                        String replyStr="";
                        keyword=keyword.toLowerCase();
                        replyStr="嘀，这里是自动应答，您刚才发送的内容是："+keyword;
                        respMessage=this.createTextMessage(replyStr, fromUserName, toUserName);
                    }
                }
            }else if(msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)){
                // 接收用户发送的事件请求内容
                String Event = requestMap.get("Event");
                //logger.info("event:"+Event);
                System.out.println("event:"+Event);
                if(StringUtils.isNotBlank(Event)){
                    if(Event.equals(MessageUtil.EVENT_TYPE_CLICK)){
                        String EventKey = requestMap.get("EventKey");
                        //logger.info("EventKey:"+EventKey);
                        System.out.println("EventKey:"+EventKey);
                        if(StringUtils.isNotBlank(EventKey)){
                            Integer keyId=Integer.parseInt(EventKey);
                            //logger.info("keyId:"+keyId);
                            if(keyId==1){
                                Member member = memberMapper.selectByOpenid(fromUserName);
                                if(member==null||member.getIsactive()==0){
                                    String replystr=Config.getString("wx.unsubscribereplystr");
                                    respMessage=this.createTextMessage(replystr, fromUserName, toUserName);
                                    return respMessage;
                                }
                                if(member.getIsactive()==0){
                                    String replystr="尊敬的用户，您还不是会员，成为会员后即可获取专属推广码";
                                    respMessage=this.createTextMessage(replystr, fromUserName, toUserName);
                                    return respMessage;
                                }
                                String headImg = member.getHeadimg();
                                String myQrcode = this.getMemberEwm(member.getOpenid());
                                String nickName=member.getNickname();
                                String qrmodePath= request.getSession().getServletContext().getRealPath("")+"/staticwx/qrmode.jpg";
                                String rootImgPath=Config.getString("img.root.path");
                                String myAdviceImgPath=ImgUtil.trsfAdviceImg(headImg,myQrcode,nickName,rootImgPath,qrmodePath);
                                String appId=Config.getString("wx.appid");
                                String appSecret=Config.getString("wx.appsecret");
                                String accessToken = this.getAccessToken(appId, appSecret);
                                JSONObject resultJSON = this.addMaterialEver(new File(myAdviceImgPath), accessToken);
                                if(resultJSON==null){
                                    String replystr="获取推广码出错啦！";
                                    respMessage=this.createTextMessage(replystr, fromUserName, toUserName);
                                    return respMessage;
                                }
                                String media_id = (String)resultJSON.get("media_id");
                                return this.createImgMessage(media_id,fromUserName,toUserName);
                            }

                        }
                    }else if(Event.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)){
                        String eventKey = requestMap.get("EventKey");
                        logger.info("用户进行关注时的EventKey:"+eventKey);
                        String str[]=eventKey.split("_");
                        String state="";
                        if(str.length==2){
                            state=str[1];
                        }
                        Wx_user wxuser = wx_userMapper.selectByOpenId(fromUserName);
                        String appid=Config.getString("wx.appid");
                        String appsecret=Config.getString("wx.appsecret");
                        if(wxuser!=null){
                            wxuser.setIsattention(1);
                            wxuser.setFollowtime(new Date());
                            wx_userMapper.updateByPrimaryKey(wxuser);
                        }
                        Wx_pic_reply wxPicReply = wx_pic_replyMapper.selectSubPic();
                        Integer picId=wxPicReply!=null?wxPicReply.getId():Config.getInt("wx.subscribereplyid");
                        String replylink=Config.getString("wx.replylink");
                        String redirecturi=Config.getString("wx.redirecturi");
                        replylink=replylink.replace("APPID",appid);
                        replylink=replylink.replace("REDIRETURL",redirecturi);
                        replylink=replylink.replace("STATE",state);
                        //logger.info("回复图文消息：picId-"+picId+"              replylink-"+replylink);
                        respMessage=this.createPicMessage(picId, fromUserName, toUserName, "", replylink);
                    }else if(msgType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)){

                    }
                }

            }
        } catch (Exception e) {
            logger.info(e.getMessage());
            e.printStackTrace();
        }
        return respMessage;
    }

    public String createTextMessage(String replyStr,String fromUserName,String toUserName){
        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(fromUserName);
        textMessage.setFromUserName(toUserName);
        textMessage.setCreateTime(new Date().getTime());
        textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
        textMessage.setFuncFlag(0);
        textMessage.setContent(replyStr);
        String respMessage = MessageUtil.textMessageToXml(textMessage);
        return respMessage;
    }

    public String createPicMessage(Integer picId,String fromUserName,String toUserName,String param,String autoUrl){
        Wx_pic_reply pic = wx_pic_replyMapper.selectByPrimaryKey(picId);
        String desc = pic.getDescription();
        String title = pic.getTitle();
        String url = pic.getLink();
        if(StringUtils.isNotBlank(autoUrl)){
            url=autoUrl;
        }
        String picUrl = pic.getPicurl();
        // 创建图文消息
        NewsMessage newsMessage = new NewsMessage();
        newsMessage.setToUserName(fromUserName);
        newsMessage.setFromUserName(toUserName);
        newsMessage.setCreateTime(new Date().getTime());
        newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
        newsMessage.setFuncFlag(0);

        List<Article> articleList = new ArrayList<Article>();
        Article article = new Article();
        article.setTitle(title);
        article.setDescription(desc);
        article.setPicUrl(picUrl);
        article.setUrl(url);
        articleList.add(article);
        // 设置图文消息个数
        newsMessage.setArticleCount(articleList.size());
        // 设置图文消息包含的图文集合
        newsMessage.setArticles(articleList);
        // 将图文消息对象转换成xml字符串
        String respMessage = MessageUtil.newsMessageToXml(newsMessage);

        return respMessage;
    }

    public String createImgMessage(String mediaId,String fromUserName,String toUserName){
        System.out.println("回复图片消息："+mediaId);
        // 创建图消息
        ImgMessage newsMessage = new ImgMessage();
        newsMessage.setToUserName(fromUserName);
        newsMessage.setFromUserName(toUserName);
        newsMessage.setCreateTime(new Date().getTime());
        newsMessage.setMsgType(MessageUtil.REQ_MESSAGE_TYPE_IMAGE);
        Image img=new Image();
        img.setMediaId(mediaId);
        newsMessage.setFuncFlag(0);
        newsMessage.setImage(img);
        String respMessage = MessageUtil.imgMessageToXml(newsMessage);
        return respMessage;
    }


    public boolean createMenu(){
        List<Wx_menu> menuList = wx_menuMapper.findListByParentId(0);
        JSONObject jsonObject = new JSONObject();
        JSONArray jsArray=new JSONArray();
        for (Wx_menu menu : menuList) {
            JSONObject jet=new JSONObject();
            jet.put("name", menu.getMenuname());
            Integer fatherId=menu.getId();
            List<Wx_menu> childList = wx_menuMapper.findListByParentId(fatherId);
            if(childList.size()>0){
                JSONArray jsonArray=new JSONArray();
                for (Wx_menu m : childList) {
                    JSONObject j=new JSONObject();
                    j.put("type", m.getMenutype());
                    j.put("name", m.getMenuname());
                    if("click".equals(m.getMenutype())){
                        j.put("key", m.getKeyval());
                    }else if("view".equals(m.getMenutype())){
                        j.put("url", m.getMenuurl());
                    }
                    jsonArray.add(j);
                }
                jet.put("sub_button", jsonArray);
            }else{
                jet.put("type", menu.getMenutype());
                if("click".equals(menu.getMenutype())){
                    jet.put("key", menu.getKeyval());
                }else if("view".equals(menu.getMenutype())){
                    jet.put("url", menu.getMenuurl());
                }

            }
            jsArray.add(jet);
        }
        jsonObject.put("button", jsArray);
        String json=jsonObject.toString();
        System.out.println("json:"+json);
        String appId=Config.getString("wx.appid");
        String appSecret=Config.getString("wx.appsecret");
        String token=this.getAccessToken(appId,appSecret);
        String url="https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
        url=url.replace("ACCESS_TOKEN", token);
        JSONObject jt=HttpClient.httpRequest(url,"POST",json);
        System.out.println("result:"+jt.toString());
        System.out.println("创建按钮成功");
        return true;
    }

    @Override
    public JSONObject getWxUserByOpenId(String openId, String access_token) {
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
        logger.info("WxConfigServiceImpl/getObjByOpenId url:" + url);
        url = url.replace("ACCESS_TOKEN", access_token);
        url = url.replace("OPENID", openId);
        logger.info("WxConfigServiceImpl/getObjByOpenId replace之后的url:" + url);
        String result = HttpClient.get(url);
        if (StringUtils.isNotBlank(result)) {
            logger.info("WxConfigServiceImpl/getObjByOpenId result：" + result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            return jsonObject;
        }
        return null;
    }

    @Override
    public void addUserInfo(JSONObject userJson) {
        Wx_user user = new Wx_user();
        String openid = (String) userJson.get("openid");
        String nickname = (String) userJson.get("nickname");
        nickname = EmojiFilter.filterEmoji(nickname);
        Integer sex = (Integer) userJson.get("sex");
        String city = (String) userJson.get("city");
        String province = (String) userJson.get("province");
        String country = (String) userJson.get("country");
        String headimgurl = (String) userJson.get("headimgurl");
        String unionid = (String) userJson.get("unionid");
        Integer groupid = (Integer) userJson.get("groupid");
        user.setCity(city);
        user.setCountry(country);
        user.setGroupid(groupid);
        user.setHeadimg(headimgurl);
        user.setNickname(nickname);
        user.setOpenid(openid);
        user.setProvince(province);
        user.setUnionid(unionid);
        user.setGender(sex);
        user.setFollowtime(new Date());
        wx_userMapper.insert(user);
    }

    @Override
    public JSONObject getOpenId(String code) {
        JSONObject ret = new JSONObject();
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
        url = url.replace("APPID", Config.getString("wx.appid"));
        url = url.replace("SECRET", Config.getString("wx.appsecret"));
        url = url.replace("CODE", code);
        logger.info("WxConfigServiceImpl/getOpenId replace之后的url:" + url);
        String result = HttpClient.get(url);
        JSONObject jsonObject = JSONObject.parseObject(result);
        String openId = (String) jsonObject.get("openid");
        String accessToken = (String) jsonObject.get("access_token");
        if (StringUtils.isBlank(openId) || StringUtils.isBlank(accessToken)) {
            ret.put("status", "error");
        } else {
            ret.put("status", "ok");
        }
        ret.put("openId", openId);
        ret.put("accessToken", accessToken);
        return ret;
    }

    @Override
    public Member setMemberData(String code,Integer parentId) {
                Member member=null;
                JSONObject reb = this.getOpenId(code);//获取openId、accessToken
                logger.info("WxConfigServiceImpl/setMemberData reb:"+reb.toString());
                String sta=reb.getString("status");
                if("ok".equals(sta)){
                    String openId = reb.getString("openId");
                    String accessToken = reb.getString("accessToken");
                    logger.info("WxConfigServiceImpl/setMemberData openId:"+openId);
                    logger.info("WxConfigServiceImpl/setMemberData accessToken:"+accessToken);
                    member=memberMapper.selectByOpenid(openId);//根据openI查询member表中，对应的member数据
                    if(member==null){
                        member=new Member();
                        member.setOpenid(openId);
                        member.setCreatetime(new Date());
                        Wx_user wxUser = wx_userMapper.selectByOpenId(openId);
                        if(wxUser==null){
                            JSONObject userJson = this.getWxUserByOpenId(openId,accessToken);
                            String nickname = (String) userJson.get("nickname");
                            nickname = EmojiFilter.filterEmoji(nickname);
                            member.setNickname(nickname);
                            member.setHeadimg((String) userJson.get("headimgurl"));
                            this.addUserInfo(userJson);
                        }else if(wxUser!=null){
                            member.setNickname( wxUser.getNickname());
                            member.setHeadimg( wxUser.getHeadimg());
                        }
                        if(parentId!=null){
                            member.setParentid(parentId);
                        }
                        member.setIsactive((byte)0);
                        member.setIscheckname((byte)0);
                        member.setIsmerchant((byte)0);
                        memberMapper.insert(member);

                        member=memberMapper.selectByOpenid(openId);
                        Mb_account account=new Mb_account();
                        account.setBalance(new BigDecimal(0));
                        account.setIntegral(0);
                        account.setMemberid(member.getId());
                        account.setRebate(new BigDecimal(0));
                        mb_accountMapper.insert(account);
                    }
            }
        return member;
    }

    public String getJsapiTicket(){
        Integer id=Config.getInt("wx.configid");
        Wx_config config = wx_configMapper.selectByPrimaryKey(id);
        String ticket="";
        if(config!=null){
            if(!this.isNeedUpdateTicket(config)){
                System.out.println("数据库ticket");
                ticket= config.getTicket();
            }else{
                System.out.println("接口ticket");
                String appId=config.getAppid();
                String appSecret=config.getAppsecret();
                String accessToken=this.getAccessToken(appId, appSecret);

                String url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
                url=url.replace("ACCESS_TOKEN", accessToken);
                String result=HttpClient.get(url);
                JSONObject jsonObject= JSONObject.parseObject(result);
                ticket=(String)jsonObject.get("ticket");
                config.setAccesstoken(accessToken);
                config.setTicket(ticket);
                config.setTickettime(new Date());
                config.setTokentime(new Date());
                wx_configMapper.updateByPrimaryKey(config);
            }
        }
        return ticket;
    }

    public boolean isNeedUpdateTicket(Wx_config wechat){
        Date lastUpdateTime=wechat.getTickettime();
        if(lastUpdateTime==null){
            return true;
        }
        long oldTimesMillis=lastUpdateTime.getTime();
        long newTimesMillis=new Date().getTime();
        if(newTimesMillis-oldTimesMillis>3600*1000){
            return true;
        }else{
            return false;
        }
    }

    public boolean isNeedUpdateToken(Wx_config wechat){
        Date lastUpdateTime=wechat.getTokentime();
        if(lastUpdateTime==null){
            return true;
        }
        long oldTimesMillis=lastUpdateTime.getTime();
        long newTimesMillis=new Date().getTime();
        if(newTimesMillis-oldTimesMillis>3600*1000){
            return true;
        }else{
            return false;
        }
    }

    @Override
    public String getAccessToken(String appId, String appSecret) {
        Integer id=Config.getInt("wx.configid");
        Wx_config config = wx_configMapper.selectByPrimaryKey(id);
        String accessToken="";
        if(!this.isNeedUpdateToken(config)){
            System.out.println("数据库token");
            accessToken= config.getAccesstoken();
            return  accessToken;
        }
        String url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
        url=url.replace("APPID", appId);
        url=url.replace("APPSECRET", appSecret);
        String result= HttpClient.get(url);
        JSONObject jsonObject= JSONObject.parseObject(result);
        accessToken=(String)jsonObject.get("access_token");
        config.setAccesstoken(accessToken);
        config.setTokentime(new Date());
        wx_configMapper.updateByPrimaryKey(config);
        return accessToken;
    }

    public String getMemberEwm(String openId){
        Member member = memberMapper.selectByOpenid(openId);
        if(member==null) {
            return null;
        }
        String myQrcode = member.getExtcode();
        if(StringUtils.isNotBlank(myQrcode)){
            long lang = new Date().getTime() - member.getExtinvalidtime().getTime();
            if(lang<604800){
                return myQrcode;
            }
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("expire_seconds", 604800);//7天
        jsonObject.put("action_name", "QR_SCENE");//临时二维码
        JSONObject jsObject = new JSONObject();
        jsObject.put("scene_id", member.getId());

        JSONObject jsob=new JSONObject();
        jsob.put("scene", jsObject.toString());

        jsonObject.put("action_info", jsob.toString());

        String json=jsonObject.toString();
        String appid = Config.getString("wx.appid");
        String appsecret = Config.getString("wx.appsecret");
        String token = this.getAccessToken(appid, appsecret);
        String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN";
        url = url.replace("ACCESS_TOKEN", token);
        JSONObject rt = HttpClient.httpRequest(url,"POST",json);
        String ticket = (String) rt.get("ticket");
        if (StringUtils.isBlank(ticket)) {
            return "";
        }
        url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
        String result = url.replace("TICKET", ticket);
        member.setExtcode(result);
        member.setExtinvalidtime(new Date());
        memberMapper.updateByPrimaryKey(member);
        return result;

    }


    public   JSONObject addMaterialEver(File file,String accessToken) throws Exception {
        try {
            String path="https://api.weixin.qq.com/cgi-bin/material/add_material?access_token="+accessToken+"&type=image";
            String result=connectHttpsByPost(path, null, file);
            result=result.replaceAll("[\\\\]", "");
            System.out.println("result========"+result);
            JSONObject resultJSON=JSONObject.parseObject(result);
            if(resultJSON==null){
                return null;
            }
            if(resultJSON.get("media_id")==null){
                return null;
            }
            return resultJSON;
        } catch (Exception e) {
            throw e;
        }
    }

    public static  String connectHttpsByPost(String path, String KK, File file) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
        URL urlObj = new URL(path);
        //连接
        HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();
        String result = null;
        con.setDoInput(true);

        con.setDoOutput(true);

        con.setUseCaches(false); // post方式不能使用缓存

        // 设置请求头信息
        con.setRequestProperty("Connection", "Keep-Alive");
        con.setRequestProperty("Charset", "UTF-8");
        // 设置边界
        String BOUNDARY = "----------" + System.currentTimeMillis();
        con.setRequestProperty("Content-Type",
                "multipart/form-data; boundary="
                        + BOUNDARY);

        // 请求正文信息
        // 第一部分：
        StringBuilder sb = new StringBuilder();
        sb.append("--"); // 必须多两道线
        sb.append(BOUNDARY);
        sb.append("\r\n");
        sb.append("Content-Disposition: form-data;name=\"media\";filelength=\"" + file.length() + "\";filename=\""

                + file.getName() + "\"\r\n");
        sb.append("Content-Type:application/octet-stream\r\n\r\n");
        byte[] head = sb.toString().getBytes("utf-8");
        // 获得输出流
        OutputStream out = new DataOutputStream(con.getOutputStream());
        // 输出表头
        out.write(head);

        // 文件正文部分
        // 把文件已流文件的方式 推入到url中
        DataInputStream in = new DataInputStream(new FileInputStream(file));
        int bytes = 0;
        byte[] bufferOut = new byte[1024];
        while ((bytes = in.read(bufferOut)) != -1) {
            out.write(bufferOut, 0, bytes);
        }
        in.close();
        // 结尾部分
        byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
        out.write(foot);
        out.flush();
        out.close();
        StringBuffer buffer = new StringBuffer();
        BufferedReader reader = null;
        try {
            // 定义BufferedReader输入流来读取URL的响应
            reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            if (result == null) {
                result = buffer.toString();
            }
        } catch (IOException e) {
            System.out.println("发送POST请求出现异常！" + e);
            e.printStackTrace();
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        return result;
    }
}